﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GeneralClasses;
using Algorithm;

namespace Interface
{
    public partial class frmCreateSchedule : Form
    {
        public Form opener;
        public Schedule weeklySchedule;
        List<Shift> shifts;
        Shift selectedShift;
        Schedule scheduleTemplate;

        public frmCreateSchedule(Form Opener)
        {
            opener = Opener;
            InitializeComponent();

            //put the scheduleTemplate here do it doesn't get reset when refresh()
            //is called
            scheduleTemplate = Schedule.getWeeklyTemplateSchedule();

            //the load data function loads data from the database, but since this is a blank shift, its not in the database
            //Department currentDep = Department.loadData(current.getDepartmentID);

            foreach (Shift current in scheduleTemplate.ShiftMasterList)
            {
                Department currentDep = null;
                bool found = false;

                for (int dIndex = 0; dIndex <= scheduleTemplate.DepartmentMasterList.Count - 1; dIndex++)
                {
                    for (int sIndex = 0; sIndex <= scheduleTemplate.DepartmentMasterList.ElementAt(dIndex).Shifts.Count - 1; sIndex++)
                    {
                        if (scheduleTemplate.DepartmentMasterList.ElementAt(dIndex).Shifts.ElementAt(sIndex) == current)
                        {
                            currentDep = scheduleTemplate.DepartmentMasterList.ElementAt(dIndex);
                            found = true;
                            break;
                        }
                    }
                    if (found) break;
                }

                if (currentDep != null)
                {
                    current.getDepartmentID = currentDep.DepartmentID;
                }
            }
        }

        void refresh()
        {
            selectedShift = null;

            List<Person> people = Person.loadAllActiveNurses();

            cmbEmployee.Items.Clear();
            foreach (Person item in people)
            {
                cmbEmployee.Items.Add(item.FullName);
            }

            dgvShifts.Rows.Clear();

            shifts = scheduleTemplate.ShiftMasterList;
            int id = 0;
            //shifts = Schedule.getWeeklyTemplateSchedule().ShiftMasterList;


            foreach (Shift current in shifts)
            {
                string skills = "";
                foreach (Skill skill in current.Skills)
                {
                    skills += (skill.Name + " ");
                }

                string startTime = current.StartTime.Date.ToShortDateString() +
                    " " + current.StartTime.DayOfWeek.ToString() + " " +
                    current.StartTime.TimeOfDay.ToString();
                string endTime = current.EndTime.Date.ToShortDateString() +
                    " " + current.EndTime.DayOfWeek.ToString() + " " +
                    current.EndTime.TimeOfDay.ToString();

                string depName = "";
                string assPerson = "";

                if (current.getAssignedPersons().Count > 0)
                    assPerson = current.getAssignedPersons()[0].FullName;

                foreach (Department department in scheduleTemplate.DepartmentMasterList)
                {
                    if (department.DepartmentID == current.getDepartmentID)
                        depName = department.Name;
                }

                dgvShifts.Rows.Add(true, assPerson, current.Name, startTime, endTime,
                    "", depName, skills, id);

                id++;
            }

            //load weights
            //load vacations?
        }

        private void btnAddShift_Click(object sender, EventArgs e)
        {
            this.Hide();
            frmAddEditShift addEditShift = new frmAddEditShift(this);
            addEditShift.Show();
        }

        private void btnEditShift_Click(object sender, EventArgs e)
        {
            if (selectedShift != null)
            {
                this.Hide();

                frmAddEditShift addEditShift = new frmAddEditShift(this, selectedShift);
                addEditShift.Show();
            }
        }

        private void btnDeleteShift_Click(object sender, EventArgs e)
        {
            if (selectedShift != null)
            {
                scheduleTemplate.ShiftMasterList.Remove(selectedShift);
                refresh();

                /* This doesn't work because the shifts aren't in the DB
                if (selectedShift.removeData() < 0)
                {
                    refresh();
                }
                else
                {
                    MessageBox.Show("Problem deleting shift!");
                }
                */
            }
        }

        private void frmCreateSchedule_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (opener != null)
            {
                opener.Show();
            }
        }

        private void frmCreateSchedule_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible == true)
                refresh();
        }

        private void btnBack_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnDeleteVacation_Click(object sender, EventArgs e)
        {
            //construct vacation from selected vacation data in dgvVacations (make sure once is selected)

            if (true/*delete from database?*/)
            {
                refresh();
            }
            else
            {
                MessageBox.Show("Problem deleting vacation!");
            }
        }

        private void btnAddVacation_Click(object sender, EventArgs e)
        {
            if (true/*add to database?*/)
            {
                refresh();
            }
            else
            {
                MessageBox.Show("Problem adding vacation!");
            }
        }

        private void btnRunScheduler_Click(object sender, EventArgs e)
        {
            DateTime endTime = DateTime.Now.AddHours((double)nudScheduleRunTime.Value);
            int numSchedules = (int)nudComplexity.Value * 200;
            float time = 0.0062f * numSchedules + 28.128f;

            MessageBox.Show("The schedule is being generated.");

            //ScheduleData scheduleData = (new AlgorithmHelper()).CreateScheduleData(weeklySchedule);

            AlgorithmHelper temp_data = new AlgorithmHelper();
            DateTime today = DateTime.Today;
            //ScheduleData data = temp_data.CreateScheduleData((DateTime)dtpStartDate.Value, 7);
            Schedule scheduleTemplate = Schedule.getWeeklyTemplateSchedule((int)nudScheduleWeeks.Value);
            ScheduleData data = temp_data.CreateScheduleData(scheduleTemplate);

            Schedule_Population population = new Schedule_Population(data);
            List<Schedule> schedule_list = population.doGenetic(numSchedules, 10);

            if (schedule_list.Count > 0)
            {
                Schedule schedule = schedule_list[0];

                foreach (Schedule scheduleCmp in schedule_list)
                {
                    if (scheduleCmp.Grade > schedule.Grade)
                        schedule = scheduleCmp;
                }

                schedule.saveData();
                MessageBox.Show("The schedule generation has been completed.");
                schedule.saveAsText();
                (new frmAllShifts(schedule)).Show();
            }
            else
            {
                MessageBox.Show("ERROR: No valid schedules were generated.");
            }

            //}
            /*    
            else if (nudScheduleWeeks.Value < 1)
                MessageBox.Show("ERROR: Weeks to schedule for must be greater than 0");
            
            else
            {
            */
            /*
                AlgorithmHelper temp_data = new AlgorithmHelper();
                int num_schedules = (int)Math.Round(nudScheduleWeeks.Value);
                List <Schedule> temp_list = new List<Schedule>();
                Schedule template = Schedule.getWeeklyTemplateSchedule();
                ScheduleData data;
                Schedule_Population population;

                for(int i=0; i<num_schedules; i++)
                {
                    data = temp_data.CreateScheduleData(template);
                        template.StartDate.AddDays(7);
                        template.EndDate.AddDays(7);

                    population = new Schedule_Population(data);
                    temp_list = population.doGenetic(numSchedules, 10);
                    Schedule schedule = temp_list[0];

                    foreach(Schedule scheduleCmp in temp_list)
                    {
                        if(scheduleCmp.Grade > schedule.Grade)
                            schedule=scheduleCmp;
                    }

                    schedule.saveData();
                    schedule.saveAsText();
                    (new frmAllShifts(schedule)).Show();
                }

                MessageBox.Show("The schedule generation has been completed.");
            */
            //List<Schedule> schedule_list = new List<Schedule>();
            /*
            List<Shift> shifts = new List<Shift>();

            for (int i = 0; i < dgvShifts.ColumnCount; i++)
                shifts.Add(new Shift((DateTime)dgvShifts[i, 1].Value, (DateTime)dgvShifts[i, 2].Value));
            */

            //frmSchedulerProgress progress = new frmSchedulerProgress(opener, endTime);
            //progress.Show();
            /*
            opener = null;
            this.Close();
             */
        }

        private void dgvShifts_SelectionChanged(object sender, EventArgs e)
        {
            if (dgvShifts.SelectedRows.Count > 0)
            {
                selectedShift = shifts[(int)dgvShifts.SelectedRows[0].Cells[8].Value];
            }
        }



    }
}

